package com.yuanian.wf.service.impl;

import com.yuanian.wf.context.process.StartProcessAfterContext;
import com.yuanian.wf.context.process.StartProcessBeforeContext;
import com.yuanian.wf.event.process.StartProcessAfterEvent;
import com.yuanian.wf.event.process.StartProcessBeforeEvent;
import com.yuanian.wf.exception.WfException;
import com.yuanian.wf.pojo.dto.CompleteTaskDto;
import com.yuanian.wf.pojo.dto.StartProcessDto;
import com.yuanian.wf.service.ProcessService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class ProcessServiceImpl implements ProcessService, ApplicationContextAware {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    private ApplicationContext applicationContext;

    @Autowired
    private TaskServiceImpl taskServiceImpl;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void startProcess(StartProcessDto startProcessDto) {
        startProcessDto.getVariables().put("flag", startProcessDto.getAct());
        //发布流程开启前的事件
        this.applicationContext.publishEvent(new StartProcessBeforeEvent("流程开启前的事件", new StartProcessBeforeContext(startProcessDto)));
        //获取业务逻辑执行完后，生成的业务ID
        String businessKey = startProcessDto.getDataId();
        if (businessKey == null || businessKey.trim().length() == 0) {
            throw new WfException("开启流程前,请设置businessKey,例子:event.getContext().getStartProcessDto().setBusinessKey(\"雪花算法ID\")");
        }
        //开启流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(startProcessDto.getProcessKey(), businessKey, startProcessDto.getVariables());
        //发布流程开启后的事件
        this.applicationContext.publishEvent(new StartProcessAfterEvent("流程开启后的事件", new StartProcessAfterContext(startProcessDto, processInstance)));

        //开始节点自动流转到下一个节点
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();

        CompleteTaskDto completeTaskDto = new CompleteTaskDto();
        completeTaskDto.setTaskId(task.getId());
        completeTaskDto.setAct(startProcessDto.getAct());
        completeTaskDto.setVariables(startProcessDto.getVariables());
        completeTaskDto.setBusinessData(startProcessDto.getBusinessData());
        completeTaskDto.setProcessKey(startProcessDto.getProcessKey());
        taskServiceImpl.completeTask(completeTaskDto);

    }

}
